#include "irrlicht.h"

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

using namespace std;

enum
{
    ID_IsNotPickable = 0,
    IDFlag_IsPickable = 1 << 0,
    IDFlag_IsHighlightable = 1 << 1
};

int loadMap(stringw& mapName)
{
    IrrlichtDevice *device = createDevice( EDT_OPENGL, dimension2d<u32>(800, 600), 32, 0, 0, 0, 0);
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();
    ITriangleSelector* selector = 0;

    //Sakrivanje kursora
    device->getCursorControl()->setVisible(false);

    //Učitavanje arhiva
    device->getFileSystem()->addFileArchive("./mitp-base/maps.pk3");
    device->getFileSystem()->addFileArchive("./mitp-base/textures.pk3");
    device->getFileSystem()->addFileArchive("./mitp-base/others.pk3");

    IQ3LevelMesh* map_mesh = (IQ3LevelMesh*) smgr->getMesh(mapName);
    ISceneNode* map_node = 0;

    //Učitavanje shadera na mapi
    	if ( map_mesh )
	{
		const scene::IMesh * const additional_mesh = map_mesh->getMesh(quake3::E_Q3_MESH_ITEMS);

		for ( u32 i = 0; i!= additional_mesh->getMeshBufferCount(); ++i )
		{
			const IMeshBuffer* meshBuffer = additional_mesh->getMeshBuffer(i);
			const video::SMaterial& material = meshBuffer->getMaterial();

			const s32 shaderIndex = (s32) material.MaterialTypeParam2;

			const quake3::IShader *shader = map_mesh->getShader(shaderIndex);
			if (0 == shader)
			{
				continue;
			}
            map_node = smgr->addQuake3SceneNode(meshBuffer, shader);
		}
	}
	//Octree optimizacija
    if (map_mesh)
        map_node = smgr->addOctreeSceneNode(map_mesh->getMesh(0), 0, IDFlag_IsPickable, 1024);
    //Triangle selektor za collision
     if (map_node)
    {
        selector = smgr->createOctreeTriangleSelector(map_mesh->getMesh(0), map_node, 128);
        map_node->setTriangleSelector(selector);
    }
    //Kamera
    ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 50.0f, .3f, ID_IsNotPickable, 0, 0, true, 3.f);
    //Pozicioniranje kamere u odnosu na info_player_start entry
    if ( map_mesh )
	{
		quake3::tQ3EntityList &entityList = map_mesh->getEntityList();

		quake3::IEntity search;
		search.name = "info_player_start";

		s32 index = entityList.binary_search(search);
		if (index >= 0)
		{
			s32 notEndList;
			do
			{
				const quake3::SVarGroup *group = entityList[index].getGroup(1);

				u32 parsepos = 0;
				const core::vector3df pos =
					quake3::getAsVector3df(group->get("origin"), parsepos);

				parsepos = 0;
				const f32 angle = quake3::getAsFloat(group->get("angle"), parsepos);

				core::vector3df target(0.f, 0.f, 1.f);
				target.rotateXZBy(angle);

				camera->setPosition(pos);
				camera->setTarget(pos + target);

				++index;
				notEndList = index == 2;
			} while ( notEndList );
		}
	}
	//Dodajemo collision response animator na kameru
	if (selector)
    {
        ISceneNodeAnimator* coll_anim = smgr->createCollisionResponseAnimator(
            selector, camera, vector3df(4,8,4),
            vector3df(0,-10,0), vector3df(0,20,0));
        selector->drop();
        camera->addAnimator(coll_anim);
        coll_anim->drop();
    }
    //Renderujemo sve
    while(device->run())
    {
        driver->beginScene(true, true, SColor(255,128,128,128));

        smgr->drawAll();
        guienv->drawAll();

        driver->endScene();
    }
    return 0;
}
